Skip to content

07 datetime日期时间

写代码经常要处理时间——记录日志要时间戳,设置超时要计算时间差,展示给用户要格式化日期。Python的datetime模块就是专门干这个的。

datetime模块提供了几个核心类:date处理日期,time处理时间,datetime处理日期+时间,timedelta处理时间间隔。

一、获取当前时间

1.1 当前日期

python
from datetime import date

today = date.today()
print(today)          # 2026-06-13
print(today.year)     # 2026
print(today.month)    # 6
print(today.day)      # 13

1.2 当前日期时间

python
from datetime import datetime

now = datetime.now()
print(now)            # 2026-06-13 10:30:45.123456
print(now.year)       # 2026
print(now.month)      # 6
print(now.day)        # 13
print(now.hour)       # 10
print(now.minute)     # 30
print(now.second)     # 45
print(now.microsecond) # 123456

1.3 UTC时间

python
from datetime import datetime, timezone

# UTC时间(世界标准时间)
utc_now = datetime.now(timezone.utc)
print(utc_now)  # 2026-06-13 02:30:45.123456+00:00

# 或者用utcnow()(3.12+已弃用,建议用上面的方式)
utc_now = datetime.utcnow()

二、创建日期时间

2.1 构造函数

python
from datetime import date, datetime

# 创建日期
d = date(2026, 6, 13)
print(d)  # 2026-06-13

# 创建日期时间
dt = datetime(2026, 6, 13, 10, 30, 0)
print(dt)  # 2026-06-13 10:30:00

# 可以省略部分参数
dt = datetime(2026, 6, 13)  # 时间默认为00:00:00

2.2 从字符串解析

python
from datetime import datetime

# 从ISO格式解析
dt = datetime.fromisoformat("2026-06-13T10:30:00")
print(dt)  # 2026-06-13 10:30:00

# 带时区的ISO格式
dt = datetime.fromisoformat("2026-06-13T10:30:00+08:00")

2.3 从时间戳创建

python
from datetime import datetime

# 当前时间戳(秒)
timestamp = datetime.now().timestamp()
print(timestamp)  # 1750000000.123456

# 从时间戳创建datetime
dt = datetime.fromtimestamp(timestamp)
print(dt)  # 2026-06-13 10:30:00.123456

# 从时间戳创建date
from datetime import date
d = date.fromtimestamp(timestamp)
print(d)  # 2026-06-13

三、时间间隔:timedelta

3.1 创建时间间隔

python
from datetime import timedelta

# 创建时间间隔
td = timedelta(days=7)
td = timedelta(hours=2, minutes=30)
td = timedelta(weeks=1, days=3)
td = timedelta(days=1, seconds=3600)

3.2 时间计算

python
from datetime import datetime, timedelta

now = datetime.now()

# 7天后
future = now + timedelta(days=7)
print(future)

# 3小时前
past = now - timedelta(hours=3)
print(past)

# 1周前
last_week = now - timedelta(weeks=1)

# 计算两个时间的差
diff = future - now
print(diff.days)         # 7
print(diff.seconds)      # 0
print(diff.total_seconds())  # 604800.0

3.3 timedelta的属性

python
from datetime import timedelta

td = timedelta(days=7, hours=2, minutes=30, seconds=15)

td.days          # 7
td.seconds       # 9015 (2*3600 + 30*60 + 15)
td.total_seconds()  # 618615.0

# 转换为其他单位
td / timedelta(hours=1)    # 170.5(总小时数)
td / timedelta(minutes=1)  # 10230.25(总分钟数)

四、格式化输出

4.1 strftime()

把日期时间对象格式化为字符串。

python
from datetime import datetime

now = datetime.now()

# 常用格式
now.strftime("%Y-%m-%d")          # '2026-06-13'
now.strftime("%Y-%m-%d %H:%M:%S") # '2026-06-13 10:30:45'
now.strftime("%Y年%m月%d日")       # '2026年06月13日'
now.strftime("%H:%M")              # '10:30'

4.2 常用格式码

格式码含义示例
%Y四位年份2026
%m月份(01-12)06
%d日(01-31)13
%H24小时制(00-23)10
%I12小时制(01-12)10
%M分钟(00-59)30
%S秒(00-59)45
%f微秒123456
%A星期全名Friday
%a星期缩写Fri
%B月份全名June
%b月份缩写Jun
%pAM/PMAM
%j年内天数(001-366)164
%U年内周数(周日为起始)23
%W年内周数(周一为起始)23
%w星期几(0=周日)5
%Z时区名CST
%zUTC偏移+0800
%%字面上的%%

4.3 strptime()

把字符串解析为datetime对象。

python
from datetime import datetime

# 解析日期字符串
dt = datetime.strptime("2026-06-13", "%Y-%m-%d")
print(dt)  # 2026-06-13 00:00:00

# 解析完整日期时间
dt = datetime.strptime("2026-06-13 10:30:45", "%Y-%m-%d %H:%M:%S")

# 解析中文格式
dt = datetime.strptime("2026年06月13日", "%Y年%m月%d日")

4.4 isoformat()

生成ISO 8601格式字符串。

python
from datetime import datetime

now = datetime.now()

now.isoformat()  # '2026-06-13T10:30:45.123456'

# 带时区
from datetime import timezone
now_utc = datetime.now(timezone.utc)
now_utc.isoformat()  # '2026-06-13T02:30:45.123456+00:00'

五、时间戳

5.1 获取时间戳

python
from datetime import datetime

now = datetime.now()

# 转为时间戳(浮点数,秒)
timestamp = now.timestamp()
print(timestamp)  # 1750000000.123456

# 整数时间戳
int_timestamp = int(now.timestamp())
print(int_timestamp)  # 1750000000

# 毫秒时间戳
ms_timestamp = int(now.timestamp() * 1000)
print(ms_timestamp)  # 1750000000123

5.2 从时间戳创建

python
from datetime import datetime

# 秒级时间戳
dt = datetime.fromtimestamp(1750000000)

# 毫秒时间戳
dt = datetime.fromtimestamp(1750000000123 / 1000)

六、星期几

python
from datetime import date

today = date.today()

# weekday():0=周一,6=周日
today.weekday()  # 4(周五)

# isoweekday():1=周一,7=周日
today.isoweekday()  # 5(周五)

# 获取星期名称
import calendar
calendar.day_name[today.weekday()]  # 'Friday'

七、实用技巧

7.1 计算年龄

python
from datetime import date

def calculate_age(birthdate):
    today = date.today()
    age = today.year - birthdate.year
    if (today.month, today.day) < (birthdate.month, birthdate.day):
        age -= 1
    return age

birthday = date(1998, 6, 13)
print(f"年龄: {calculate_age(birthday)}岁")

7.2 计算两个日期之间的天数

python
from datetime import date

d1 = date(2026, 1, 1)
d2 = date(2026, 6, 13)

diff = d2 - d1
print(f"相差{diff.days}天")  # 相差163天

7.3 获取本月第一天和最后一天

python
from datetime import date
import calendar

today = date.today()

# 本月第一天
first_day = today.replace(day=1)

# 本月最后一天
last_day = today.replace(day=calendar.monthrange(today.year, today.month)[1])

print(f"本月: {first_day} ~ {last_day}")

7.4 判断是否为工作日

python
from datetime import date

def is_workday(d):
    """判断是否为工作日(周一到周五)"""
    return d.weekday() < 5

today = date.today()
print(f"今天{'是' if is_workday(today) else '不是'}工作日")

7.5 格式化为相对时间

python
from datetime import datetime, timedelta

def time_ago(dt):
    """格式化为相对时间"""
    now = datetime.now()
    diff = now - dt

    if diff < timedelta(minutes=1):
        return "刚刚"
    elif diff < timedelta(hours=1):
        return f"{diff.seconds // 60}分钟前"
    elif diff < timedelta(days=1):
        return f"{diff.seconds // 3600}小时前"
    elif diff < timedelta(days=30):
        return f"{diff.days}天前"
    elif diff < timedelta(days=365):
        return f"{diff.days // 30}个月前"
    else:
        return f"{diff.days // 365}年前"

post_time = datetime(2026, 6, 1, 10, 0, 0)
print(time_ago(post_time))  # 12天前

7.6 处理时区

python
from datetime import datetime, timezone, timedelta

# 创建带时区的时间
china_tz = timezone(timedelta(hours=8))
now_china = datetime.now(china_tz)
print(now_china)  # 2026-06-13 10:30:45+08:00

# 转换时区
utc_tz = timezone.utc
now_utc = now_china.astimezone(utc_tz)
print(now_utc)  # 2026-06-13 02:30:45+00:00

# 去掉时区信息
naive = now_china.replace(tzinfo=None)

八、与time模块的区别

datetimetime模块都能处理时间,但用途不同:

python
# datetime模块:面向对象,适合日期计算
from datetime import datetime, timedelta
now = datetime.now()
future = now + timedelta(days=7)

# time模块:底层时间操作,适合性能敏感场景
import time
timestamp = time.time()  # 获取时间戳
time.sleep(1)            # 休眠1秒
特性datetimetime
风格面向对象函数式
日期计算方便不方便
时间戳需要转换直接支持
休眠不支持sleep()
精度微秒依赖系统

一般情况下用datetime就够了。

九、总结

datetime模块的核心类:

用途
date日期(年月日)
time时间(时分秒微秒)
datetime日期+时间
timedelta时间间隔
timezone时区

常用操作:

操作代码
获取当前时间datetime.now()
获取当前日期date.today()
格式化输出dt.strftime("%Y-%m-%d")
解析字符串datetime.strptime(s, fmt)
时间计算dt + timedelta(days=7)
计算差值(dt2 - dt1).days
获取时间戳dt.timestamp()
从时间戳创建datetime.fromtimestamp(ts)

记住datetime.now()strftime()strptime()timedelta这四个就够应付大部分场景了。